package dao

import (
	"errors"
	"fmt"
	"log"
	"strings"
	"time"
	__ "user_srv/basic/userproto"
	"user_srv/handler/models"
)

// 创建个人用户退款记录
func PersonalUserRefund(in *__.PersonalUserRefundReq) (*models.PersonalUserRefund, error) {
	// 1. 参数验证
	if err := validateRefundRequest(in); err != nil {
		log.Printf("退款记录参数验证失败: %v", err)
		return nil, fmt.Errorf("参数验证失败: %w", err)
	}

	// 2. 解析退款时间
	refundTime, err := parseRefundTime(in.RefundTime)
	if err != nil {
		log.Printf("退款时间解析失败: %v", err)
		return nil, fmt.Errorf("退款时间格式错误: %w", err)
	}

	// 3. 验证退款金额合理性
	if err := validateRefundAmount(in.RefundAmount); err != nil {
		log.Printf("退款金额验证失败: %v", err)
		return nil, fmt.Errorf("退款金额验证失败: %w", err)
	}

	// 4. 检查用户是否存在
	if err := validateUserExists(in.UserId); err != nil {
		log.Printf("用户验证失败: %v", err)
		return nil, fmt.Errorf("用户验证失败: %w", err)
	}

	// 5. 检查退款流水号是否已存在
	if err := validateRefundTransactionIdUnique(in.RefundTransactionId); err != nil {
		log.Printf("退款流水号验证失败: %v", err)
		return nil, fmt.Errorf("退款流水号验证失败: %w", err)
	}

	// 6. 验证退款原因合理性
	if err := validateRefundReason(in.RefundReason); err != nil {
		log.Printf("退款原因验证失败: %v", err)
		return nil, fmt.Errorf("退款原因验证失败: %w", err)
	}

	// 7. 创建退款记录
	refund := models.PersonalUserRefund{
		UserId:                  in.UserId,
		RefundTransactionId:     in.RefundTransactionId,
		UserName:                in.UserName,
		Mobile:                  in.Mobile,
		UserType:                in.UserType,
		RefundTime:              refundTime,
		RefundAmount:            in.RefundAmount,
		RefundReason:            in.RefundReason,
		ThirdPartyTransactionId: in.ThirdPartyTransactionId,
		RefundChannel:           in.RefundChannel,
		RefundStatus:            in.RefundStatus,
	}

	// 8. 保存到数据库
	if err := refund.Create(); err != nil {
		log.Printf("创建退款记录失败: %v", err)
		return nil, fmt.Errorf("创建退款记录失败: %w", err)
	}

	log.Printf("成功创建退款记录，用户ID: %d, 流水号: %s", in.UserId, in.RefundTransactionId)
	return &refund, nil
}

// 查询个人用户退款记录列表
func PersonalUserRefundList(in *__.PersonalUserRefundListReq) (*__.PersonalUserRefundListResp, error) {
	var refund models.PersonalUserRefund

	// 设置默认分页参数
	page := int(in.Page)
	pageSize := int(in.PageSize)
	if page <= 0 {
		page = 1
	}
	if pageSize <= 0 {
		pageSize = 10
	}

	// 查询数据
	list, total, err := refund.GetList(
		in.RefundTransactionId,
		in.Mobile,
		in.UserName,
		in.RefundChannel,
		in.StartTime,
		in.EndTime,
		page,
		pageSize,
	)
	if err != nil {
		return nil, errors.New("查询退款记录失败: " + err.Error())
	}

	// 转换为响应格式
	var items []*__.PersonalUserRefundItem
	for _, item := range list {
		items = append(items, &__.PersonalUserRefundItem{
			Id:                      int32(item.Id),
			UserId:                  item.UserId,
			RefundTransactionId:     item.RefundTransactionId,
			UserName:                item.UserName,
			Mobile:                  item.Mobile,
			UserType:                item.UserType,
			RefundTime:              item.RefundTime.Format("2006-01-02 15:04:05"),
			RefundAmount:            item.RefundAmount,
			RefundReason:            item.RefundReason,
			ThirdPartyTransactionId: item.ThirdPartyTransactionId,
			RefundChannel:           item.RefundChannel,
			RefundStatus:            item.RefundStatus,
		})
	}

	return &__.PersonalUserRefundListResp{
		List:     items,
		Total:    int32(total),
		Page:     int32(page),
		PageSize: int32(pageSize),
	}, nil
}

// validateRefundRequest 验证退款请求参数
func validateRefundRequest(in *__.PersonalUserRefundReq) error {
	if in == nil {
		return errors.New("请求参数不能为空")
	}

	// 验证必填字段
	if in.UserId <= 0 {
		return errors.New("用户ID必须大于0")
	}

	if strings.TrimSpace(in.RefundTransactionId) == "" {
		return errors.New("退款流水号不能为空")
	}

	if strings.TrimSpace(in.UserName) == "" {
		return errors.New("用户名不能为空")
	}

	if strings.TrimSpace(in.Mobile) == "" {
		return errors.New("手机号不能为空")
	}

	// 验证手机号格式
	if !isValidMobile(in.Mobile) {
		return errors.New("手机号格式不正确")
	}

	if strings.TrimSpace(in.RefundChannel) == "" {
		return errors.New("退款渠道不能为空")
	}

	if strings.TrimSpace(in.RefundAmount) == "" {
		return errors.New("退款金额不能为空")
	}

	if strings.TrimSpace(in.RefundReason) == "" {
		return errors.New("退款原因不能为空")
	}

	if strings.TrimSpace(in.RefundStatus) == "" {
		return errors.New("退款状态不能为空")
	}

	// 验证流水号格式
	if !isValidTransactionId(in.RefundTransactionId) {
		return errors.New("退款流水号格式不正确")
	}

	return nil
}

// parseRefundTime 解析退款时间
func parseRefundTime(timeStr string) (time.Time, error) {
	if strings.TrimSpace(timeStr) == "" {
		return time.Now(), nil
	}

	// 尝试多种时间格式
	formats := []string{
		"2006-01-02 15:04:05",
		"2006-01-02T15:04:05Z",
		"2006-01-02T15:04:05",
		"2006-01-02",
	}

	for _, format := range formats {
		if t, err := time.Parse(format, timeStr); err == nil {
			// 验证时间不能是未来时间
			if t.After(time.Now()) {
				return time.Time{}, errors.New("退款时间不能是未来时间")
			}
			// 验证时间不能太早（比如超过1年）
			if t.Before(time.Now().AddDate(-1, 0, 0)) {
				return time.Time{}, errors.New("退款时间不能超过1年")
			}
			return t, nil
		}
	}

	return time.Time{}, errors.New("时间格式不正确")
}

// validateRefundAmount 验证退款金额合理性
func validateRefundAmount(amount string) error {
	// 验证退款金额
	refundAmount, err := parseAmount(amount)
	if err != nil {
		return fmt.Errorf("退款金额格式错误: %w", err)
	}

	if refundAmount <= 0 {
		return errors.New("退款金额必须大于0")
	}

	if refundAmount > 100000 { // 单次退款限额10万
		return errors.New("单次退款金额不能超过10万元")
	}

	return nil
}

// validateRefundTransactionIdUnique 验证退款流水号唯一性
func validateRefundTransactionIdUnique(transactionId string) error {
	var existingRefund models.PersonalUserRefund
	existingRefund.RefundTransactionId = transactionId
	err := existingRefund.GetByTransactionId()
	if err == nil {
		return errors.New("退款流水号已存在")
	}
	return nil
}

// validateRefundReason 验证退款原因合理性
func validateRefundReason(reason string) error {
	reason = strings.TrimSpace(reason)
	if len(reason) < 5 {
		return errors.New("退款原因描述不能少于5个字符")
	}
	if len(reason) > 500 {
		return errors.New("退款原因描述不能超过500个字符")
	}

	// 检查是否包含敏感词（这里可以扩展敏感词列表）
	sensitiveWords := []string{"测试", "test", "TEST"}
	for _, word := range sensitiveWords {
		if strings.Contains(strings.ToLower(reason), strings.ToLower(word)) {
			return fmt.Errorf("退款原因不能包含敏感词: %s", word)
		}
	}

	return nil
}
